//1.左值
//左值是一个表示数据的表达式，比如：变量名、解引用的指针变量。一般地，我们可以获取它的地址和对它赋值，但被 const 修饰后的左值，不能给它赋值，但是仍然可以取它的地址。
//简言之 可以取地址的对象就是左值

//以下 a, p, *p, b都是左值
int a=3;
int *p = &a;
*p;
const int b = 2;


//2.右值
//右值也是一个表示数据的表达式，比如：字面常量、表达式返回值，传值返回函数的返回值（是传值返回，而非传引用返回），右值不能出现在赋值符号的左边且不能取地址。
//总体而言，不可以取地址的对象就是右值。

//以下 都是右值
10;
x + y;
fmin(x, y);

//再通俗讲，可以放到=(赋值符号)左边的是左值，只能放到=右边的是右值
//但区分左值和右值，终究还是要看能不能取地址






//2.左值引用和右值引用

//左值引用就是对左值的引用， 给左值取别名
int& ra = a;
int*& rp = p;
int& r = *p;
const int& rb=b;


//右值引用就是对右值的引用，给右值取别名
//右值引用的表示是在具体的变量类型名称后加两个 &，比如：int&& rr = 4;
int&& rr1=10;
double&& rr2 = x+y;
double&& rr3 = fmin(x, y);

//总结
//1.左值引用只能引用左值，不能直接引用右值
//2.const左值引用既可以引用左值，也可以引用右值
//3.右值引用只能引用右值，不能直接引用左值
//4.右值引用可以引用被move的左值
